import numpy as np

import config
from market import Market
from trader import Trader


class BaseAMM:
    def probability_after_trade(self, market: Market, is_true: bool, share: float) -> float:
        """
        假设交易发生，计算true选项价格
        """
        raise NotImplementedError

    def trade(self, market: Market, is_true: bool, share: float):
        raise NotImplementedError

    def price(self, market: Market) -> float:
        """
        根据市场情况计算true选项价格
        """
        raise NotImplementedError

    def probability(self, market: Market) -> float:
        """
        根据市场情况计算true选项概率
        """
        raise NotImplementedError

    def execute(self, noisy_probability: float, market: Market, trader: Trader):
        expect_probability = trader.expect(noisy_probability)  # 交易者估计true选项概率

        current_probability = self.probability(market)

        # 如果交易者的估计true选项概率与市场的当前true选项概率之差小于交易者的噪声水平，则交易者认为价格偏离属于正常波动，因此不进行交易
        if np.abs(expect_probability - current_probability) < trader.noisy_degree:
            return

        # 如果估计true选项概率大于当前true选项概率则买入true选项，否则买入false选项
        is_true = expect_probability > current_probability

        # 交易者此次交易的数量，计算条件为使得交易者效用最大，即使得交易后true选项概率等于估计true选项概率，交易数最大为config.TRADING_MAX_SHARE
        trade_share = 0
        for share in range(1, config.TRADING_MAX_SHARE * 10 + 1):
            trade_share = share / 10

            if is_true:
                if expect_probability < self.probability_after_trade(market, is_true, trade_share):
                    break
            else:
                if expect_probability > self.probability_after_trade(market, is_true, trade_share):
                    break

        # 计算出最优交易的数量，进行交易
        self.trade(market, is_true, trade_share)

        market.price_records.append(self.price(market))
